package cn.wolfcode.crm.shrio.realm;

import cn.wolfcode.crm.domain.Employee;
import cn.wolfcode.crm.mapper.EmployeeMapper;
import cn.wolfcode.crm.mapper.PermissionMapper;
import cn.wolfcode.crm.mapper.RoleMapper;
import cn.wolfcode.crm.service.IEmployeeService;
import cn.wolfcode.crm.service.IPermissionService;
import cn.wolfcode.crm.service.IRoleService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class EmployeeRealm extends AuthorizingRealm {

    //从容器中找到 credentialsMatcher ,注入进去
    @Autowired
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
    }

    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 提供认证相关信息
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取登录的用户名
        Object principal = token.getPrincipal();
        //查询数据库中是否有此用户 有就返回相反信息
        Employee employee = employeeMapper.selectByName(principal.toString());
        if (employee != null) {
            //Simpleinfo四个参数 用户 用户密码 密码加密的盐 当前信息从哪个数据源查出来
            //第一个参数是subject里面的身份信息,希望以后获取到的是员工对象,这里就传入员工对象
            return new SimpleAuthenticationInfo(employee, employee.getPassword(),
                    ByteSource.Util.bytes(employee.getName()), "EmployeeRealm");
        }
        // 若账号不正确，返回 null
        return null;
    }

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    /**
     * 提供授权相关信息
     *
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("======提供授权相关信息=======");
        Subject subject = SecurityUtils.getSubject();
        Employee employee = (Employee) subject.getPrincipal();//获取用户信息 认证时传入的第一个参数
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (employee.isAdmin()) { //判断是否是超管 是就给赋予所以权限
            info.addRole("admin");
            info.addStringPermission("*:*");
            return info;
        } else {
            //非超管 就根据用户id 查询出角色跟权限 返回给shiro进行授权
            List<String> roles = roleMapper.selectSnByEmployeeId(employee.getId());
            List<String> permissions = permissionMapper.getPermissionByEmployeeId(employee.getId());
            info.addRoles(roles);
            info.addStringPermissions(permissions);
            return info;
        }
    }


}
